<?php
class Utility
{/*{{{*/
	public static function convertEncoding($arr, $toEncoding, $fromEncoding='', $convertKey=false)
    {/*{{{*/
        if ($toEncoding == $fromEncoding)
        {
            return $arr;
        }
        if (is_array($arr))
        {
            $keys = array_keys($arr);
            for ($i=0,$max=count($keys);$i<$max;$i++)
            {
                $key = $keys[$i];
                $res = $arr[$key];
                if ($convertKey)
                {
                    unset($arr[$key]);
                    $key = mb_convert_encoding($key, $toEncoding, $fromEncoding);
                }

                if (is_array($res))
                {
                    $res = self::convertEncoding($res, $toEncoding, $fromEncoding, $convertKey);
                }
                else
                {
                    $res = mb_convert_encoding($res, $toEncoding, $fromEncoding);
                }

                $arr[$key] = $res;
            }
        }
        else
        {
            $arr = mb_convert_encoding($arr, $toEncoding, $fromEncoding);
        }
        return $arr;
    }/*}}}*/

    public static function getContents($url, $post = 0)
    {/*{{{*/
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL, $url );
        curl_setopt($ch,CURLOPT_HEADER, false);
        curl_setopt($ch,CURLOPT_USERAGENT, "Mozilla/99.99 (compatible; MSIE 99.99; Windows XP 99.99)");
        curl_setopt($ch,CURLOPT_TIMEOUT,10);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
        if ($post)
        {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        }
        $result = curl_exec($ch);
        curl_close( $ch );
    
        return $result;
    }/*}}}*/

    static public function requestByProxy($proxy, $urlInfo, $params=array(), $timeout=3)
    {/*{{{*/
        $request = self::parseUrl($urlInfo) . self::parseParams($params);

        $ch = curl_init();

        $proxyUrl = self::parseUrl($proxy);
        $header = array('Cache-Control: no-cache');
        curl_setopt($ch, CURLOPT_PROXY, $proxyUrl);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

        curl_setopt($ch, CURLOPT_URL, $request);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
        curl_close($ch);

        return $response;
    }/*}}}*/

    static public function request($urlInfo, $params=array(), $timeout=3)
    {/*{{{*/
        $request = self::parseUrl($urlInfo) . self::parseParams($params);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $request);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        if(isset($urlInfo['domain']))
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('host:'.$urlInfo['domain']));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $retryTimes = 0;
        $maxRetryTimes = ConfigLoader::getConfig('CURL_RETRY_TIME');
        while($errno && $retryTimes < $maxRetryTimes)
        {
            $retryTimes++;
            $time = date('[d/M/Y:H:i:s O]', time());
            $message = implode(' ', array($time, '[error]', $retryTimes, $errno, curl_error($ch)));
            $message .= "\n";
            error_log($message, 3, ConfigLoader::getConfig('LOGPATH')."error.log");
            $response =  curl_exec($ch);
            $errno = curl_errno($ch);
            if(!$errno)
                break;
        }
        curl_close($ch);

        return $response;
    }/*}}}*/

    static public function simple_request($url,$data='',$timeout=3,$host=null)
    {/*{{{*/
        $info = "";
        if(is_array($data))
        {
            foreach($data as $key=>$val)
            {
                if (is_array($val))
                {
                    foreach ($val as $k=>$v)
                    {
                        $info .= $key.'['.$k.']='.urlencode($v).'&';
                    }
                }
                else
                {
                    $info .="$key=".urlencode($val)."&";
                }
            } 
        }
        $ch = curl_init(); 
        curl_setopt($ch,CURLOPT_POST,1);
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $info);

        if(!is_null($host))
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('host:'.$host));
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }/*}}}*/

    static public function multiRequest($requests, $timeout=3)
    {/*{{{*/
        $mh = curl_multi_init();

        foreach($requests as $request)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $request);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_multi_add_handle($mh, $ch);
            $conn[] = $ch;
        }
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while($mrc == CURLM_CALL_MULTI_PERFORM);

        while ($active and $mrc == CURLM_OK)
        {
            if (curl_multi_select($mh) != -1)
            {
                do {
                    $mrc = curl_multi_exec($mh, $active);
                } while ($mrc == CURLM_CALL_MULTI_PERFORM);
            }
        }

        $cnt = count($requests);
        for($i =0; $i < $cnt; $i++)
        {
            if(!curl_errno($conn[$i]))
            {
                $res[$i] = curl_multi_getcontent($conn[$i]);
            }
            curl_multi_remove_handle($mh, $conn[$i]);
            curl_close($conn[$i]);
        }
        curl_multi_close($mh);

        return $res;
    }/*}}}*/

    static public function multiRequestByProxy($proxy, $requests, $timeout=3)
    {/*{{{*/
        $proxyUrl = self::parseUrl($proxy);
        $header = array('Cache-Control: no-cache');
        $mh = curl_multi_init();

        foreach($requests as $request)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_PROXY, $proxyUrl);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
            curl_setopt($ch, CURLOPT_URL, $request);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_multi_add_handle($mh, $ch);
            $conn[] = $ch;
        }

        do {
            $mrc = curl_multi_exec($mh, $active);
        } while($mrc == CURLM_CALL_MULTI_PERFORM);

        while ($active and $mrc == CURLM_OK)
        {
            if (curl_multi_select($mh) != -1)
            {
                do {
                    $mrc = curl_multi_exec($mh, $active);
                } while ($mrc == CURLM_CALL_MULTI_PERFORM);
            }
        }

        $cnt = count($requests);
        for($i =0; $i < $cnt; $i++)
        {
            if(!curl_errno($conn[$i]))
            {
                $res[$i] = curl_multi_getcontent($conn[$i]);
            }
            curl_multi_remove_handle($mh, $conn[$i]);
            curl_close($conn[$i]);
        }
        curl_multi_close($mh);

        return $res;
    }/*}}}*/

    static public function parseUrl($urlInfo)
    {/*{{{*/
        $scheme = isset($urlInfo['scheme']) ? $urlInfo['scheme'] : 'http';
        $port = isset($urlInfo['port']) ? $urlInfo['port'] : 80;
        $path = isset($urlInfo['path']) ? $urlInfo['path'] : '';
        if(is_array($urlInfo['host']))
        {
            $key  = rand(0,(count($urlInfo['host'])-1));
            $host = $urlInfo['host'][$key]; 
        }else
        {
            $host = $urlInfo['host'];
        }

        $request = $scheme . '://'. $host .':'. $port . $path;
        return $request;
    }/*}}}*/

    static public function parseParams($params)
    {/*{{{*/
        $paramString = '';
        $pairs = array();
        foreach($params as $key => $value)
        {
            $pair = $key .'='. $value;
            array_push($pairs, $pair);
        }
        if($query = implode('&', $pairs))
        {
            $paramString .= '?' . $query;
        }

        return $paramString;
    }/*}}}*/

    public function unescape($str) 
    { /*{{{*/
        $str = rawurldecode($str); 
        preg_match_all("/%u.{4}|&#x.{4};|&#d+;|.+/U",$str,$r); 
        $ar = $r[0]; 
        foreach($ar as $k=>$v) 
        { 
            if(substr($v,0,2) == "%u") 
                $ar[$k] = iconv("UCS-2","GBK",pack("H4",substr($v,-4))); 
            elseif(substr($v,0,3) == "&#x") 
                $ar[$k] = iconv("UCS-2","GBK",pack("H4",substr($v,3,-1))); 
            elseif(substr($v,0,2) == "&#") { 
                $ar[$k] = iconv("UCS-2","GBK",pack("n",substr($v,2,-1))); 
            } 
        }
        return join("",$ar); 
    }/*}}}*/
    
    public function phpescape($str)
    {/*{{{*/
        preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/",$str,$newstr);
        $ar = $newstr[0];
        $reString = "";
        foreach($ar as $k=>$v){
            if(ord($ar[$k])>=127){
                $tmpString=bin2hex(iconv("GBK","ucs-2",$v));
                if (!eregi("WIN",PHP_OS)){
                    $tmpString = substr($tmpString,2,2).substr($tmpString,0,2);
                }
                $reString.="%u".$tmpString;
            } else 
                {
                $reString.= rawurlencode($v);
            }
        }
        return $reString;
    }/*}}}*/

    static public function substrCn($str,$start,$len,$type=1)
    {/*{{{*/
        $tmp = "";
        if ( $type == 2) 
        {
            $str = strip_tags($str);
        }
        if(strlen($str) > $len)
        {
            for ( $i=0; $i<$start+$len-2; $i++)
            {
                $tmpstr =(ord($str[$i])>127)?$str[$i].$str[++$i]:$str[$i];
                if ( $i>=$start) 
                {
                    $tmp .= $tmpstr;
                }
            }
            return $tmp;
        }else{
            return $str;
        }
    }/*}}}*/

    static public function getCmsFileContents($file)
    {/*{{{*/
        $cmsComment = "<!-- *** generated by qihoo *** -->";
        $cmsPath = "/usr/local/apache2/htdocs/wenda/kd/";
        $path = $cmsPath . $file; 
        if (false == file_exists ($path))
        {
            return "";
        } 
        if (false == is_readable($path))
        {
            return "";
        } 
                
        return  trim(str_replace($cmsComment , "" , file_get_contents($path)));
    }/*}}}*/

    static public function dfopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) 
    {
        $return = '';
        $matches = parse_url($url);
        $host = $matches['host'];
        $path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
        $port = !empty($matches['port']) ? $matches['port'] : 80;

        if($post) {
            $out = "POST $path HTTP/1.0\r\n";
            $out .= "Accept: */*\r\n";
            //$out .= "Referer: $boardurl\r\n";
            $out .= "Accept-Language: zh-cn\r\n";
            $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
            $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
            $out .= "Host: $host\r\n";
            $out .= 'Content-Length: '.strlen($post)."\r\n";
            $out .= "Connection: Close\r\n";
            $out .= "Cache-Control: no-cache\r\n";
            $out .= "Cookie: $cookie\r\n\r\n";
            $out .= $post;
        } else {
            $out = "GET $path HTTP/1.0\r\n";
            $out .= "Accept: */*\r\n";
            //$out .= "Referer: $boardurl\r\n";
            $out .= "Accept-Language: zh-cn\r\n";
            $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
            $out .= "Host: $host\r\n";
            $out .= "Connection: Close\r\n";
            $out .= "Cookie: $cookie\r\n\r\n";
        }
        $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
        if(!$fp) {
            return '';
        } else {
            stream_set_blocking($fp, $block);
            stream_set_timeout($fp, $timeout);
            @fwrite($fp, $out);
            $status = stream_get_meta_data($fp);
            if(!$status['timed_out']) {
                while (!feof($fp)) {
                    if(($header = @fgets($fp)) && ($header == "\r\n" ||  $header == "\n")) {
                        break;
                    }
                }

                $stop = false;
                while(!feof($fp) && !$stop) {
                    $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
                    $return .= $data;
                    if($limit) {
                        $limit -= strlen($data);
                        $stop = $limit <= 0;
                    }
                }
            }
            @fclose($fp);
            return $return;
        }
}

    static public function xml_to_array($xml)
    {
       $array = @(simplexml_load_string($xml));
       if($array !==false)
       {
            $array = (array)$array;
            foreach ($array as $key=>$item)
            {
                $array[$key]  =  self::struct_to_array((array)$item);
            }
            ksort($array['FavoriteItem']);
            return $array;
       }else
       {
            return array(); 
       }
    }

    static public function struct_to_array($item)
    {
        if(!is_string($item)) 
        {
            $item = (array)$item;
            foreach ($item as $key=>$val)
            {
               $item[$key]  =  self::struct_to_array($val);
            }
        }else
        {
            $item = iconv('utf-8','gbk',htmlspecialchars(addslashes($item)));
        }
        return $item; 
    }
    
  /**
   * 
   *
   * @param String $uri
   * @return String URI with version onSuccess,Boolean false onFailure
   */
	static public function QgetVersionURI($uri)
	{
		if(count($uri))
		{
			$DocumentRoot = $_SERVER['DOCUMENT_ROOT'];
			$filepath = $DocumentRoot.substr($uri,0);
			return $uri."?v".filemtime($filepath);
		}
		return false;
	}
    
	static public function echoJson($data)
	{
		header("Content-Type: application/json");
		$msg = Utility::convertEncoding($data, 'utf-8', 'gbk');
		echo json_encode($msg);
		exit;
	}
	
	/**
	 * 
	 *
	 * @param unknown_type $str
	 */
	static public function isZhEnChar($str)
	{
		return (false === ereg('^[A-Za-z'.chr(0xa1).'-'.chr(0xff).']+$',$str)) ? false : true ;
	}
	
	static public function getParam($key, $default = null) {
		if (isset($_REQUEST[$key])) {
			return $_REQUEST[$key];
		}else if ($default!=null) {
			return $default;
		}else {
			return false;
		}
	}
}/*}}}*/

?>
